package com.anxin.registerManagement.service;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.jwt.JWTUtil;
import com.anxin.registerManagement.bean.dto.RoomDto;
import com.anxin.registerManagement.bean.jo.RoomSearchJo;
import com.anxin.registerManagement.bean.persist.Dormitory;
import com.anxin.registerManagement.bean.persist.Room;
import com.anxin.registerManagement.bean.persist.User;
import com.anxin.registerManagement.exception.BusinessException;
import com.anxin.registerManagement.mapper.DormitoryMapper;
import com.anxin.registerManagement.mapper.RoomMapper;
import com.anxin.registerManagement.mapper.UserMapper;
import com.anxin.registerManagement.util.Const;
import com.anxin.registerManagement.util.jwt.JwtUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;

/**
 * @author 叶前呈
 * @date 2022/1/30 14:32
 */
@Service
public class RoomService {

    private static Logger logger = LoggerFactory.getLogger(RoomService.class);

    @Autowired
    RoomMapper roomMapper;

    @Autowired
    DormitoryMapper dormitoryMapper;

    @Autowired
    UserMapper userMapper;

    /**
     * 查询房间
     */
    public PageInfo<RoomDto> getRoomList(RoomSearchJo roomSearchJo) {
        if (!ObjectUtil.isEmpty(roomSearchJo.getPageNum()) && !ObjectUtil.isEmpty(roomSearchJo.getPageSize())) {
            PageHelper.startPage(roomSearchJo.getPageNum(), roomSearchJo.getPageSize());
        }
        // 查询房间，这里使用mybatis的结果映像集resultmap
        // TODO:这里有2种方案，1.循环插入宿舍，2.使用结果映像集，方案一可能循环耗时，方案二不走索引，不知道哪个方案好
        List<RoomDto> roomDtoList = roomMapper.getRoomList(roomSearchJo);
        return new PageInfo<>(roomDtoList);
    }


    /**
     * 添加房间
     */
    public void addRoom(Room room) {
        room.setIsFree(true);
        // TODO:需要判断房间是否存在
        roomMapper.insert(room);
    }

    /**
     * 修改房间
     */
    public void updateRoom(Room room) {
        // TODO:需要判断房间是否存在
        roomMapper.updateById(room);
    }

    /**
     * 删除房间
     */
    public void deleteRoom(int id) {
        roomMapper.deleteById(id);
    }

    /**
     * 获取当前用户房间信息
     */
    public RoomDto getRoomByUser() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes()).getRequest();
        // TODO:这里应该通过当前用户jwt解析出id然后进行搜索
        String jwt = request.getHeader(Const.jwtName);
        String id = JwtUtil.getClaim(jwt, "id");

        //查询用户，TODO：这里逻辑可以和入住整合在一起
        User user = userMapper.selectById(1);
        // 如果用户没有入住，则直接返回空
        if (ObjectUtil.isEmpty(user.getRoomId())) {
            return null;
        }
        Room room = roomMapper.selectById(user.getRoomId());
        Dormitory dormitory = dormitoryMapper.selectById(room.getDormitoryId());
        RoomDto roomDto = new RoomDto();
        BeanUtils.copyProperties(room, roomDto);
        roomDto.setDormitory(dormitory);
        return roomDto;
    }

    /**
     * 入住
     */
    @Transactional(rollbackFor = Exception.class)
    public void checkIn(Integer roomId) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes()).getRequest();
        String jwt = request.getHeader(Const.jwtName);
        String id = JwtUtil.getClaim(jwt, "id");

        // 查询用户
        // TODO:这里同理，需要从jwt中获取
        User user = userMapper.selectById(1);
        if (!ObjectUtil.isEmpty(user.getRoomId())) {
            throw new BusinessException("只能选择一个房间，请先退房后再进行操作");
        }
        // TODO:这里还需要判断房间是否存在，这里需要修改用户的房间，并且修改房间是否空闲
        // TODO:这里同理，需要从jwt中获取
        Room room = roomMapper.selectById(roomId);
        if (ObjectUtil.isEmpty(room)) {
            throw new BusinessException("房间不存在");
        }
        // 修改房间
        room.setIsFree(false);
        roomMapper.updateById(room);
        // 修改用户
        user.setRoomId(roomId);
        userMapper.updateById(user);
    }

    /**
     * 退房
     */
    public void checkOut(Integer roomId) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes()).getRequest();
        String jwt = request.getHeader(Const.jwtName);
//        String id = JwtUtil.getClaim(jwt, "id");
        String id = "1";
        // TODO:这里同理，需要从jwt中获取

        // 查询用户
        // TODO:逻辑：先判断房间是否存在，然后通过房间id和用户id判断用户是否存在
        // TODO:然后进行修改

        Room room = roomMapper.selectById(roomId);
        if (ObjectUtil.isEmpty(room)) {
            throw new BusinessException("房间不存在");
        }
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getId, id).eq(User::getRoomId, roomId);
        User user = userMapper.selectOne(lambdaQueryWrapper);
        if (ObjectUtil.isEmpty(user)) {
            throw new BusinessException("该用户并没有入住该房间");
        }

        // 修改房间空闲
        room.setIsFree(true);
        roomMapper.updateById(room);
        // 修改用户
        user.setRoomId(null);
        userMapper.updateById(user);
    }

    /**
     * 获取所有房间
     */
    public List<Room> getAllRooms() {
        return roomMapper.selectList(null);
    }

}
